#include "UltimateAndroidInputSubsystem.h"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))

UltimateAndroidInputSubsystem::UltimateAndroidInputSubsystem(
		struct android_app* state) {
	sensorManager = ASensorManager_getInstance();
	accelerometerSensor = ASensorManager_getDefaultSensor(sensorManager,
			ASENSOR_TYPE_ACCELEROMETER);
	sensorEventQueue = ASensorManager_createEventQueue(sensorManager,
			state->looper, LOOPER_ID_USER, NULL, NULL);


	accelometerInited = false;
	pointerDown = false;

}

UltimateAndroidInputSubsystem::~UltimateAndroidInputSubsystem() {
	// TODO Auto-generated destructor stub
}

void UltimateAndroidInputSubsystem::updateInput(AInputEvent* event) {

	/*
	 }*/

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
		int key = AKeyEvent_getKeyCode(event);

		if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) {
			inputStruct.pressedButtons.insert(key);

		} else if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) {
			inputStruct.pressedButtons.erase(key);
		}
	}

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {

		unsigned int flags = AMotionEvent_getAction(event)
				& AMOTION_EVENT_ACTION_MASK;

		if (flags == AMOTION_EVENT_ACTION_DOWN
				|| flags == AMOTION_EVENT_ACTION_POINTER_DOWN) {
			pointerDown = true;

			x0 = AMotionEvent_getX(event, 0);
			y0 = AMotionEvent_getY(event, 0);
		} else if (flags == AMOTION_EVENT_ACTION_UP
				|| flags == AMOTION_EVENT_ACTION_POINTER_UP) {
			pointerDown = false;

			int64_t currentPointerUpEventTime = AMotionEvent_getEventTime(event);

			bool doubleTap = abs(currentPointerUpEventTime-lastPointerUpEventTime)<500000000;
			LOGI("doubleTap=%s", doubleTap? "true":"false");

			if(doubleTap)
			{
				inputStruct.inputMap["DOUBLE_TAP"] = 1;
			}

			lastPointerUpEventTime = currentPointerUpEventTime;


			inputStruct.inputMap["POINTER_UP"] = 1;

		} else if (flags == AMOTION_EVENT_ACTION_MOVE) {
			x1 = AMotionEvent_getX(event, 0);
			y1 = AMotionEvent_getY(event, 0);

			/*Ogre::LogManager::getSingleton().logMessage(Ogre::LML_CRITICAL,
			 Ogre::StringConverter::toString(x1 - x0));
			 Ogre::LogManager::getSingleton().logMessage(Ogre::LML_CRITICAL,
			 Ogre::StringConverter::toString(y1 - y0));*/

			int modif = -1;
			if (AInputEvent_getSource(event) == AINPUT_SOURCE_TOUCHPAD) {
				modif = 1;
			}

			inputStruct.inputMap[INPUT_POINTER_REL_X] = (x1 - x0) / 2;
			inputStruct.inputMap[INPUT_POINTER_REL_Y] = ((y1 - y0) / 2)
					* (modif);

			x0 = x1;
			y0 = y1;
		}

	}

}

void UltimateAndroidInputSubsystem::clearInput() {
	for (std::map<std::string, int>::iterator i = inputStruct.inputMap.begin();
			i != inputStruct.inputMap.end(); i++) {
		(*i).second = 0;
	}

}

UltimateInputSubsystem::UltimateInputStruct * UltimateAndroidInputSubsystem::handleInput() {

	return &inputStruct;
}

void UltimateAndroidInputSubsystem::registerSensors() {
	if (accelerometerSensor != NULL) {
		ASensorEventQueue_enableSensor(sensorEventQueue, accelerometerSensor);
		// We'd like to get 60 events per second (in us).
		ASensorEventQueue_setEventRate(sensorEventQueue, accelerometerSensor,
				(1000L / 60) * 1000);
	}

}
void UltimateAndroidInputSubsystem::unRegisterSernsors() {

	if (accelerometerSensor != NULL) {
		ASensorEventQueue_disableSensor(sensorEventQueue, accelerometerSensor);
	}

}

void UltimateAndroidInputSubsystem::handleSensors() {

	if (accelerometerSensor != NULL) {
		ASensorEvent event;
		while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0) {

			/*LOGI("accelerometer: x=%f y=%f z=%f", event.acceleration.x,
					event.acceleration.y, event.acceleration.z);*/

			if(!accelometerInited)
			{
				ax=event.acceleration.x;
				ay=event.acceleration.y;
				az=event.acceleration.z;

				accelometerInited=true;
			}
			if(!pointerDown)
			{
				inputStruct.inputMap[INPUT_POINTER_REL_X] = (event.acceleration.y-ay)*2;
				inputStruct.inputMap[INPUT_POINTER_REL_Y] = (event.acceleration.x-ax)*2;
			}
		}
	}
}
